﻿using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;

namespace ECMessageQueue
{
    public class MQClient : MessageQueue
    {
        private string localIp = "0.0.0.0";
        private string serverIp;
        private int serverPort = 61050;
        private Socket socket;
        private int buffersizekb = 1024 * 2;
        private Thread connectionThread;
        private int clientId = 0;
        private string clientToken = string.Empty;

        public MQClient(string server_ip, ECLogger.Logger logger = null) : base(logger)
        {
            serverIp = server_ip;
            initSocketClient();
            runSender();
        }

        private void initSocketClient()
        {
            try
            {
                socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.Bind(new IPEndPoint(IPAddress.Parse(localIp), 0));
                socket.Connect(serverIp, serverPort);
                var buff = new byte[128];
                socket.Receive(buff);
                var recvstr = Encoding.Default.GetString(buff);
                var recvstrs = recvstr.Split(',');
                clientId = int.Parse(recvstrs[0]);
                clientToken = recvstrs[1].Substring(0, 16);
                connectionThread = new Thread(new ThreadStart(recievFromServer));
                connectionThread.Start();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private void recievFromServer()
        {
            try
            {
                while (isRunning)
                {
                    var buff = new byte[buffersizekb * 1024];
                    socket.Receive(buff);
                    MQMESSAGE mqm = bytesToMsg(buff);
                    putRecvQueue(mqm);
                    log.Debug("Recive Message from Server Len[{0}]:\r\n{1}", mqm.length, mqm.content);
                }
            }
            catch (Exception) { }
        }

        protected override void sendBySocket(MQMESSAGE mqm)
        {
            try
            {
                if (mqm == null) return;
                if (mqm.remote != 0) return;
                socket.Send(msgToBytes(mqm));
                log.Debug("Send Message to Server Len[{0}]:\r\n{0}", mqm.length, mqm.content);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void sendMessage(string msg, string token)
        {
            MQMESSAGE s = new MQMESSAGE();
            s.content = msg;
            s.remote = 0;
            s.length = msg.Length;
            s.token = token;
            sendMessage(s);
        }

        public int getId()
        {
            return clientId;
        }

        public string getClientToken()
        {
            return clientToken;
        }

        public void close()
        {
            isRunning = false;
            if (senderThread != null) senderThread.Abort();
            if (connectionThread != null) connectionThread.Abort();
            stopSender();
            socket.Close();
        }
    }
}
